home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / HPACK78S.ZIP / vms.c < prev    next >
C/C++ Source or Header  |  1992-07-27  |  13KB  |  486 lines

  1. /****************************************************************************
  2. *                                                                            *
  3. *                            HPACK Multi-System Archiver                        *
  4. *                            ===========================                        *
  5. *                                                                            *
  6. *                              VMS-Specific Routines                            *
  7. *                             VMS.C  Updated 30/06/92                        *
  8. *                                                                            *
  9. * This program is protected by copyright and as such any use or copying of    *
  10. *  this code for your own purposes directly or indirectly is highly uncool    *
  11. *                      and if you do so there will be....trubble.                *
  12. *                 And remember: We know where your kids go to school.            *
  13. *                                                                            *
  14. *         Copyright 1992  Some poor sucker :-) and Peter C. Gutmann.            *
  15. *                            All rights reserved                                *
  16. *                                                                            *
  17. ****************************************************************************/
  18.  
  19. /* VAXORCIST:  Everything looks okay to me.
  20.  
  21.    SYSMGR:  Maybe it's hibernating.
  22.  
  23.    VAXORCIST:  Unlikely.  It's probably trying to lure us into a false sense
  24.                of security.
  25.  
  26.    SYSMGR:  Sounds like VMS alright.
  27.  
  28.    - Christopher Russell */
  29.  
  30. #include <curses.h>
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <stsdef.h>
  35. #include "defs.h"
  36. #include "error.h"
  37. #include "frontend.h"
  38. #include "hpacklib.h"
  39. #include "system.h"
  40. #include "tags.h"
  41. #include "io/hpackio.h"
  42.  
  43. /* Translate HPACK return codes into a VMS-compatible format */
  44.  
  45. int translateVMSretVal( const int retVal )
  46.     {
  47.     /* Return success */
  48.     if( retVal == OK )
  49.         return( STS$K_CONTROL_INHIB_MSG | STS$K_SUCCESS );
  50.  
  51.     /* Return severity level along with error encoded into customer-defined
  52.        facility number field */
  53.     return( STS$K_CONTROL_INHIB_MSG | STS$K_FAC_NO_CUST_DEF | \
  54.             ( retVal << STS$V_FAC_NO ) | ( retVal < 100 ) ? STS$K_FATAL : \
  55.             ( retVal < 200 ) ? STS$K_ERROR : STS$K_WARNING );
  56.     }
  57.  
  58. /* Translate a filespec from canonical to VMS format */
  59.  
  60. char *translateToVMS( char *pathName, const BOOLEAN isDirPath )
  61.     {
  62.     static char vmsName[ MAX_PATH ];
  63.     int pathNameLen = strlen( pathName );
  64.     int i, startPos = 0, lastSlash = ERROR;
  65.  
  66.     /* First, look for a node/device component */
  67.     for( i = 0; i < pathNameLen; i++ )
  68.         if( pathName[ i ] == ':' )
  69.             startPos = i + 1;            /* Include ':' */
  70.  
  71.     /* Copy across the node/device component if it exists */
  72.     if( startPos )
  73.         {
  74.         strcpy( vmsName, pathName );
  75.         pathName += startPos;
  76.         pathNameLen -= startPos;
  77.         }
  78.  
  79.     /* Now scan for directory delimiters */
  80.     for( i = startPos; i < pathNameLen; i++ )
  81.         if( pathName[ i ] == SLASH )
  82.             lastSlash = i;
  83.  
  84.     /* If it's a directory path, there is no filename component */
  85.     if( isDirPath )
  86.         lastSlash = pathNameLen;
  87.  
  88.     /* If there is a path, translate it to the VMS format */
  89.     if( lastSlash != ERROR )
  90.         {
  91.         vmsName[ startPos++ ] = '[';
  92.         for( i = 0; i < lastSlash; i++ )
  93.             vmsName[ startPos++ ] = ( pathName[ i ] == SLASH ) ? '.' : pathName[ i ];
  94.         vmsName[ startPos++ ] = ']';
  95.         pathName += lastSlash + !isDirPath;    /* + 1 to skip SLASH if there is one */
  96.         }
  97.  
  98.     /* Finally, add the filename component */
  99.     strcpy( vmsName + startPos, pathName );
  100.  
  101.     return( vmsName );
  102.     }
  103.  
  104. /****************************************************************************
  105. *                                                                            *
  106. *                                HPACKLIB Functions                            *
  107. *                                                                            *
  108. ****************************************************************************/
  109.  
  110. /* Get an input character, no echo */
  111.  
  112. int hgetch( void )
  113.     {
  114.     char ch;
  115.  
  116.     noecho();
  117.     ch = getch();
  118.     echo();
  119.     return( ch );
  120.     }
  121.  
  122. /****************************************************************************
  123. *                                                                            *
  124. *                                HPACKIO Functions                            *
  125. *                                                                            *
  126. ****************************************************************************/
  127.  
  128. /* Set a file's timestamp */
  129.  
  130. void setFileTime( const char *fileName, const LONG fileTime )
  131.     {
  132.     puts( "Need to implement setFileTime" );
  133.     }
  134.  
  135. /* Rename a file */
  136.  
  137. void rename( const char *srcFile, const char *destFile )
  138.     {
  139.     char vmsSrcFile[ MAX_PATH ], vmsDestFile[ MAX_PATH ];
  140.  
  141.     translateToVMS( srcFile, vmsSrcFile );
  142.     translateToVMS( destFile, vmsDestFile );
  143.  
  144.     puts( "Need to implement rename" );
  145.     }
  146.  
  147. /* Create a directory.  This is like the usual mkdir() but we translate the
  148.    path into a VMS format (Question:  How far can *you* throw VMS?) */
  149.  
  150. int hmkdir( const char *dirName, const int attr )
  151.     {
  152.     char vmsDirName[ MAX_PATH ];
  153.  
  154.     translateToVMS( dirName, vmsDirName );
  155.     mkdir( vmsDirName, attr );
  156.     }
  157.  
  158. /* opendir(), readdir(), closedir() for Unix.  Presumably the VMS findFirst()
  159.    can be based on these + the Unix findFirst() code? */
  160.  
  161. #if 0
  162. #include <fcntl.h>
  163. #include <sys/types.h>
  164.  
  165. #include <dir.h>
  166.  
  167. #define DIRBUFSIZE        512
  168.  
  169. typedef struct {
  170.                struct stat d_stat;        /* stat() info for dir */
  171.                char d_name[ MAX_FILENAME ];
  172.                } DIRECT;
  173.  
  174. typedef struct {
  175.                int dd_fd;                /* This directories' FD */
  176.                int dd_loc;                /* Index into buffer of dir info */
  177.                int dd_size;                /* No. of entries in buffer */
  178.                char dd_buf[ DIRBUFSIZE ];    /* Buffer of dir entries */
  179.                } DIR;
  180.  
  181. DIR *opendir( const char *dirName )
  182.     {
  183.     DIR *dirPtr;
  184.     FD dirFD;
  185.  
  186.     /* Try and open directory corresponding to dirName */
  187.     if( ( dirFD = hopen( dirName, O_RDONLY ) ) != FILE_ERROR )
  188.         {
  189.         /* Allocate room for directory information */
  190.         if( ( dirPtr = ( DIR * ) hmalloc( sizeof( DIR ) ) ) != NULL )
  191.             {
  192.             /* Set up directory information */
  193.             dirPtr->dd_fd = dirFD;
  194.             dirPtr->dd_loc = 0;
  195.             dirPtr->dd_size = 0;
  196.             return( dirPtr );
  197.             }
  198.         hclose( dirFD );
  199.         }
  200.     return( NULL );
  201.     }
  202.  
  203. /* Read out the next directory entry */
  204.  
  205. DIRECT *readdir( DIR *dirPtr )
  206.     {
  207.     static DIRECT dirInfo;            /* Dir.info as we want it set out */
  208.     struct direct *diskDirInfo;        /* Dir.info as stored on disk */
  209.  
  210.     /* Grovel through dir.entries until we find a non-deleted file */
  211.     do
  212.         {
  213.         /* Check if we need to read in more of dir */
  214.         if( dirPtr->dd_loc >= dirPtr->dd_size )
  215.             {
  216.             /* Yes, read in next load of info */
  217.             dirPtr->dd_loc = 0;
  218.             if( ( dirPtr->dd_size = hread( dirPtr->dd_fd, dirPtr->dd_buf, DIRBUFSIZE ) ) == FILE_ERROR )
  219.                 /* Out of directory, return NULL dirinfo */
  220.                 return( NULL );
  221.             }
  222.  
  223.         /* Extract this directory entry and point to next location in buffer */
  224.         diskDirInfo = ( struct direct * ) ( dirPtr->dd_buf + dirPtr->dd_loc );
  225.         dirPtr->dd_loc += sizeof( struct direct );
  226.         }
  227.     while( diskDirInfo->d_ino == 0 );
  228.  
  229.     /* Move info across to struct as we want it */
  230.     strncpy( dirInfo.d_name, diskDirInfo->d_name, NAMEINDIR_LEN );
  231.     dirInfo.d_name[ NAMEINDIR_LEN ] = '\0';
  232.     stat( dirInfo.d_name, &dirInfo.d_stat );
  233.  
  234.     return( &dirInfo );
  235.     }
  236.  
  237. /* End opendir() functions */
  238.  
  239. void closedir( DIR *dirPtr )
  240.     {
  241.     hclose( dirPtr->dd_fd );
  242.     hfree( dirPtr );
  243.     }
  244. #endif /* 0 */
  245.  
  246. /* Find the first/next file in a directory */
  247.  
  248. BOOLEAN findFirst( const char *pathName, const ATTR fileAttr, FILEINFO *fileInfo )
  249.     {
  250.     char dirPath[ MAX_PATH ];
  251.     int pos;
  252.  
  253.     /* Start at first entry in this directory */
  254.     fileInfo->matchAttr = fileAttr;
  255.  
  256.     strcpy( dirPath, pathName );
  257.     if( !*dirPath )
  258.         {
  259.         /* No pathname, search current directory */
  260.         *dirPath = '.' ;
  261.         dirPath[ 1 ] = '\0';
  262.         }
  263.  
  264.     /* Check whether we want to match all files in a directory or one
  265.        particular file */
  266.     if( dirPath[ strlen( dirPath ) - 1 ] == '.' )
  267.         {
  268.         /* Try and open directory */
  269.         if( ( fileInfo->dirBuf = opendir( dirPath ) ) == NULL )
  270.             return( FALSE );
  271.         dirPath[ strlen( dirPath ) - 1 ] = '\0';    /* Zap '.' */
  272.         strcpy( fileInfo->dName, dirPath );
  273.  
  274.         /* Pull file information out of directory */
  275.         return( findNext( fileInfo ) );
  276.         }
  277.     else
  278.         {
  279.         /* Handling one particular file, just stat it */
  280.         fileInfo->dirBuf=NULL;
  281.         for( pos = strlen( dirPath ) - 1; pos != 0 && dirPath[ pos ] != SLASH; \
  282.              pos-- );
  283.         strcpy( fileInfo->fName, dirPath + pos );
  284.         if( stat( dirPath, &fileInfo->statInfo ) != ERROR )
  285.             {
  286.             fileInfo->fTime = fileInfo->statInfo.st_mtime;
  287.             fileInfo->fSize = fileInfo->statInfo.st_size;
  288.             return TRUE;
  289.             }
  290.         else
  291.             return FALSE;
  292.         }
  293.     }
  294.  
  295. BOOLEAN findNext( FILEINFO *fileInfo )
  296.     {
  297.     struct dirent *dirinfo;
  298.     char dirPath[ MAX_PATH ];
  299.  
  300.     do
  301.         {
  302.         /* Grovel through the directory skipping deleted and non-matching files */
  303.         if( ( dirinfo = readdir( fileInfo->dirBuf ) ) == NULL )
  304.             return( FALSE );
  305.  
  306.         /* Fill out fileInfo fields.  Some systems may have the stat info
  307.            available after the readdir() call, but we have to assume the
  308.            worst for the portable version */
  309.         strncpy( fileInfo->fName, dirinfo->d_name, MAX_FILENAME );
  310.         fileInfo->fName[ MAX_FILENAME ] = 0;
  311.         if( strlen( fileInfo->dName ) + strlen( fileInfo->fName ) > MAX_PATH )
  312.             error( PATH_s__TOO_LONG, dirPath );
  313.         strcpy( dirPath, fileInfo->dName );            /* Copy dirpath */
  314.         strcat( dirPath, fileInfo->fName );            /* Add filename */
  315.         stat( dirPath, &fileInfo->statInfo );
  316.         fileInfo->fTime = fileInfo->statInfo.st_mtime;
  317.         fileInfo->fSize = fileInfo->statInfo.st_size;
  318.         }
  319.     /* Sometimes we only want to match files, not directories */
  320.     while( ( fileInfo->matchAttr == ALLFILES ) ? \
  321.            ( ( fileInfo->statInfo.st_mode & S_IFMT ) == S_IFDIR ) : 0 );
  322.  
  323.     return( TRUE );
  324.     }
  325.  
  326. /* End findFirst/Next() for this directory */
  327.  
  328. void findEnd( const FILEINFO *fileInfo )
  329.     {
  330.     if( fileInfo->dirBuf != NULL )
  331.         closedir( fileInfo->dirBuf );
  332.     }
  333.  
  334. /* Get the screen size */
  335.  
  336. #define DEFAULT_ROWS        24
  337. #define DEFAULT_COLS        80
  338.  
  339. void getScreenSize( void )
  340.     {
  341.     puts( "Need to implement getScreenSize()" );    /* Use curses - see unix.c */
  342.     screenWidth = DEFAULT_COLS;
  343.     screenHeight = DEFAULT_ROWS;
  344.     }
  345.  
  346. /* Get the country we're running in */
  347.  
  348. int getCountry( void )
  349.     {
  350.     puts( "Need to implement getCountry()" );
  351.     return( 0 );    /* Default to US - see viewfile.c for country codes */
  352.     }
  353.  
  354. /* The worst-case htruncate() - open a new file, copy everything across to
  355.    the truncation point, and delete the old file.  This only works because
  356.    htruncate is almost never called and because the drive access speed is
  357.    assumed to be fast */
  358.  
  359. void moveData( const FD _inFD, const FD destFD, const long noBytes );
  360.  
  361. int htruncate( const FD theFD )
  362.     {
  363.     FD newArchiveFD;
  364.     char newArchiveName[ MAX_PATH ];
  365.     long truncatePoint;
  366.     int retVal;
  367.  
  368.     puts( "Need to implement htruncate()" );
  369.  
  370.     /* Set up temporary filename to be the archive name with a ".TMP" suffix */
  371.     strcpy( newArchiveName, archiveFileName );
  372.     strcpy( newArchiveName, strlen( newArchiveName ) - 3, "TMP" );
  373.  
  374.     if( ( newArchiveFD = hopen( newArchiveName, O_RDWR ) ) == FILE_ERROR )
  375.         error( INTERNAL_ERROR );
  376.     setOutputFD( newArchiveFD );
  377.     setInputFD( archiveFD );
  378.  
  379.     /* Use the moveData() routine to move all data up to the truncation point
  380.        to the new archive */
  381.     truncatePoint = htell( archiveFD );
  382.     hlseek( archiveFD, 0L, SEEK_SET );
  383.     _outByteCount = 0;
  384.     moveData( truncatePoint );
  385.  
  386.     /* Close and delete the old archive, and make the new archive the active
  387.        one */
  388.     retVal = hclose( archiveFD );
  389.     archiveFD = newArchiveFD;
  390.     retVal |= hunlink( archiveFileName );
  391.     return( retVal | hrename( newArchiveName, archiveName ) );
  392.     }
  393. #endif /* Various mutation-dependant truncate()'s */
  394.  
  395. /* Check whether two pathnames refer to the same file */
  396.  
  397. BOOLEAN isSameFile( const char *pathName1, const char *pathName2 )
  398.     {
  399.     struct stat statInfo1, statInfo2;
  400.  
  401.     puts( "Need to implement isSameFile()" );
  402.     stat( pathName1, &statInfo1 );    /* This will work? but is nasty */
  403.     stat( pathName2, &statInfo2 );
  404.     return( statInfo1.st_ino == statInfo2.st_ino && \
  405.             statInfo1.st_dev == statInfo2.st_dev );
  406.     }
  407.  
  408. /****************************************************************************
  409. *                                                                            *
  410. *                                SYSTEM Functions                            *
  411. *                                                                            *
  412. ****************************************************************************/
  413.  
  414. /* Lowercase a string */
  415.  
  416. void strlwr( char *string )
  417.     {
  418.     while( *string )
  419.         {
  420.         *string = tolower( *string );
  421.         string++;
  422.         }
  423.     }
  424.  
  425. /* Move a block of memory, handles overlapping blocks */
  426.  
  427. void memmove( void *dest, void *src, int length )
  428.     {
  429.     int itmp = ( length + 7 ) >> 3;
  430.  
  431.     if( dest > src )
  432.         {
  433.         dest += length;
  434.         src += length;
  435.         switch( length & 3 )
  436.             {
  437.             case 0:    do {    *--dest = *--src;
  438.             case 7:            *--dest = *--src;
  439.             case 6:            *--dest = *--src;
  440.             case 5:            *--dest = *--src;
  441.             case 4:            *--dest = *--src;
  442.             case 3:            *--dest = *--src;
  443.             case 2:            *--dest = *--src;
  444.             case 1:            *--dest = *--src;
  445.                      } while( --itmp > 0 );
  446.             }
  447.         }
  448.     else
  449.         {
  450.         switch( length & 3 )
  451.             {
  452.             case 0:    do {    *dest++ = *src++;
  453.             case 7:            *dest++ = *src++;
  454.             case 6:            *dest++ = *src++;
  455.             case 5:            *dest++ = *src++;
  456.             case 4:            *dest++ = *src++;
  457.             case 3:            *dest++ = *src++;
  458.             case 2:            *dest++ = *src++;
  459.             case 1:            *dest++ = *src++;
  460.                      } while( --itmp > 0 );
  461.             }
  462.         }
  463.     /* This was added mainly to frighten you */
  464.     }
  465.  
  466. /* Non-case-sensitive string compare */
  467.  
  468. int strnicmp( char *src, char *dest, int length )
  469.     {
  470.     char srcCh, destCh;
  471.  
  472.     while( length-- )
  473.         {
  474.         /* Need to be careful with toupper() side-effects */
  475.         srcCh = *src++;
  476.         srcCh = toupper( srcCh );
  477.         destCh = *dest++;
  478.         destCh = toupper( destCh );
  479.  
  480.         if( srcCh != destCh )
  481.             return( srcCh - destCh );
  482.         }
  483.  
  484.     return( 0 );
  485.     }
  486.